<template>
  <ul class="shapes" v-if="canvas">
    <li
      class="shape"
      v-for="(item, index) in shapeList"
      :key="index"
      @click="item.handler"
      draggable="true"
      @dragend="item.handler"
    >
      {{ item.name }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue'
import { useFabricStore } from '@/stores/fabric'
import { storeToRefs } from 'pinia'
import * as fabric from 'fabric'
import { recordRelationship, activateMinions, customProps } from '@/utils/fabricOprationTools'

const fabricStore = useFabricStore()
const { canvas } = storeToRefs(fabricStore)
const { addCustomProps } = fabricStore

addCustomProps(...customProps)

const shapeList = ref([
  {
    name: 'text',
    handler: (e) => {
      const text = new fabric.Textbox('Hello World', {
        width: 200,
        fontSize: 30,
        fontFamily: 'Arial',
        fill: 'black',
        stroke: '#c3bfbf',
        strokeWidth: 0.5,
        textAlign: 'center',
        shadow: 'green -5px -5px 3px',
      })
      canvas.value.add(text)
      setObjectPosition(e, text)
      canvas.value.setActiveObject(text)
    },
  },
  {
    name: 'rect',
    icon: 'rect.svg',
    handler: (e) => {
      const rect = new fabric.Rect({
        fill: 'rgb(226, 192, 141)',
        width: 200,
        height: 80,
        stroke: 'black',
        strokeWidth: 5,
      })
      canvas.value.add(rect)
      setObjectPosition(e, rect)
      canvas.value.setActiveObject(rect)
    },
  },
  {
    name: 'group',
    icon: 'rect.svg',
    handler: (e) => {
      const rect = new fabric.Rect({
        fill: 'rgb(226, 192, 141)',
        width: 200,
        height: 80,
        stroke: '#ffca28',
        strokeWidth: 5,
      })
      const text = new fabric.Textbox('Hello World', {
        width: 200,
        fontSize: 30,
        fontFamily: 'Arial',
        fill: 'black',
        stroke: '#c3bfbf',
        strokeWidth: 0.5,
        textAlign: 'center',
        shadow: 'green -5px -5px 3px',
      })
      const group = new fabric.Group([rect, text], {
        stroke: '#ffca28',
        strokeWidth: 5,
        angle: 45,
      })
      canvas.value.add(group)
      setObjectPosition(e, group)
      canvas.value.setActiveObject(group)
    },
  },
  {
    name: 'textBox',
    handler: (e) => {
      const rect = new fabric.Rect({
        fill: 'rgb(226, 192, 141)',
        width: 200,
        height: 80,
        stroke: '#ffca28',
        strokeWidth: 5,
      })
      const text = new fabric.Textbox('Hello World', {
        width: 200,
        fontSize: 30,
        fontFamily: 'Arial',
        fill: 'black',
        stroke: '#c3bfbf',
        strokeWidth: 0.5,
        textAlign: 'center',
        shadow: 'green -5px -5px 3px',
      })
      canvas.value.add(rect, text)
      recordRelationship(rect, [text])
      activateMinions(rect, [text])
      const sel = new fabric.ActiveSelection([rect, text])
      setObjectPosition(e, sel)
      canvas.value.setActiveObject(sel)
    },
  },
  {
    name: 'line',
    handler: (e) => {
      const line = new fabric.Line([0, 0, 100, 0], {
        stroke: 'black',
        strokeWidth: 2,
      })
      canvas.value.add(line)
      setObjectPosition(e, line)
      canvas.value.setActiveObject(line)
    },
  },
])

/**
 *
 * @param {MouseEvent} e
 * @param {fabric.ActiveSelection|fabric.Group|fabric.FabricObject} obj
 */
const setObjectPosition = (e, obj) => {
  if (e.type === 'dragend') {
    const point = canvas.value.getScenePoint(e)
    obj.set({
      left: point.x,
      top: point.y,
    })
  } else {
    canvas.value.centerObject(obj)
  }
}
</script>

<style lang="scss" scoped>
.shapes {
  padding: 1rem 0;
  display: grid;
  grid-auto-rows: 3rem;
  gap: 0.3rem;
  place-items: center;
  .shape {
    width: 4.2rem;
    height: 2.5rem;
    background-color: #001245;
    border: 1px solid rgba(221, 221, 221, 0.5);
    font-size: 0.95rem;
    line-height: 1;
    text-align: center;
    align-content: center;
    color: #ddd;
    border-radius: 5px;
    cursor: pointer;
    user-select: none;
    &:hover {
      color: #409eff;
      outline: 0.2px solid rgba(64, 158, 255, 0.5);
      transform: translateX(-2px);
    }
  }
}
</style>
